import base64
import collections
import functools
import importlib
import inspect
import itertools
import json
import logging
import operator
import os
import platform
import re
import requests
import shutil
import signal
import socket
import subprocess
import sys
import tempfile
import threading
import time
import unittest
import werkzeug.urls
from contextlib import contextmanager
from datetime import datetime, date
from unittest.mock import patch

from decorator import decorator
from lxml import etree, html

from odoo.models import BaseModel
from odoo.osv.expression import normalize_domain, TRUE_LEAF, FALSE_LEAF
from odoo.tools import pycompat
from odoo.tools import single_email_re
from odoo.tools.misc import find_in_path
from odoo.tools.safe_eval import safe_eval

try:
    from itertools import zip_longest as izip_longest
except ImportError:
    from itertools import izip_longest

try:
    import websocket
except ImportError:
    websocket = None

try:
    from xmlrpc import client as xmlrpclib
except ImportError:
    import xmlrpclib

import odoo
import pprint
from odoo import api
from odoo.service import security

_logger = logging.getLogger(__name__)

ADDONS_PATH = odoo.tools.config['addons_path']
HOST = '127.0.0.1'
PORT = odoo.tools.config['http_port']
ADMIN_USER_ID = odoo.SUPERUSER_ID

def get_db_name():
    db = odoo.tools.config['db_name']

    if not db and hasattr(threading.current_thread(), 'dbname'):
        pass
    return db

DB = get_db_name()

def at_install(flag):
    pass

def post_install(flag):
    pass

def new_test_user(env, login='', groups='base.group_user', context=None, **kwargs):
    pass

class OdooSuite(unittest.suite.TestSuite):
    if sys.version_info < (3, 8):
        def _handleClassSetUp(self, test, result):
            pass

        def _createClassOrModuleLevelException(self, result, exc, method_name, parent, info=None):
            pass

        def _addClassOrModuleLevelException(self, result, exception, errorName, info=None):
            pass

        def _tearDownPreviousClass(self, test, result):
            pass

class TreeCase(unittest.TestCase):
    if sys.version_info < (3, 8):
        _class_cleanups = []

        @classmethod
        def addClassCleanup(cls, function, *args, **kwargs):
            pass

        @classmethod
        def doClassCleanups(cls):
            pass

    def __init__(self, methodName='runTest'):
        pass

    def assertTreesEqual(self, n1, n2, msg=None):
        pass

class MetaCase(type):
    def __init__(cls, name, bases, attrs):
        super(MetaCase, cls).__init__(name, bases, attrs)
        if cls.__module__.startswith('odoo.addons.'):
            pass

class BaseCase(TreeCase, MetaCase('DummyCase', (object,), {})):
    longMessage = True
    warm = True

    def cursor(self):
        pass

    @property
    def uid(self):
        pass

    @uid.setter
    def uid(self, user):
        pass

    def ref(self, xid):
        pass

    def browse_ref(self, xid):
        pass

    @contextmanager
    def _assertRaises(self, exception):
        pass

    def assertRaises(self, exception, func=None, *args, **kwargs):
        pass

    @contextmanager
    def assertQueryCount(self, default=0, **counters):
        pass

    def assertRecordValues(self, records, expected_values):
        pass

    def shortDescription(self):
        pass

    if not pycompat.PY2:
        def assertItemsEqual(self, a, b, msg=None):
            pass

class TransactionCase(BaseCase):
    def setUp(self):
        pass

    def patch(self, obj, key, val):
        pass

    def patch_order(self, model, order):
        pass


class SingleTransactionCase(BaseCase):
    @classmethod
    def setUpClass(cls):
        pass

savepoint_seq = itertools.count()
class SavepointCase(SingleTransactionCase):
    def setUp(self):
        pass

class ChromeBrowser():
    def __init__(self, logger):
        pass

    def signal_handler(self, sig, frame):
        pass

    def stop(self):
        pass

    @property
    def executable(self):
        pass

    def _spawn_chrome(self, cmd):
        pass

    def _chrome_start(self):
        pass

    def _find_websocket(self):
        pass

    def _json_command(self, command, timeout=3, get_key=None):
        pass

    def _open_websocket(self):
        pass

    def _websocket_send(self, method, params=None):
        pass

    def _websocket_wait_id(self, awaited_id, timeout=10):
        pass

    def _websocket_wait_event(self, method, params=None, timeout=10):
        pass

    def _get_shotname(self, prefix, ext):
        pass

    def take_screenshot(self, prefix='failed'):
        pass

    def _save_screencast(self, prefix='failed'):
        pass

    def start_screencast(self):
        pass

    def set_cookie(self, name, value, path, domain):
        pass

    def delete_cookie(self, name, **kwargs):
        pass

    def _wait_ready(self, ready_code, timeout=60):
        pass

    def _wait_code_ok(self, code, timeout):
        pass

    def navigate_to(self, url, wait_stop=False):
        pass

    def clear(self):
        pass


class HttpCase(TransactionCase):
    registry_test_mode = True
    browser = None

    def __init__(self, methodName='runTest'):
        pass

    @classmethod
    def terminate_browser(cls):
        pass

    @classmethod
    def start_browser(cls, logger):
        pass

    def setUp(self):
        pass

    def url_open(self, url, data=None, timeout=10):
        pass

    def _wait_remaining_requests(self):
        pass

    def authenticate(self, user, password):
        pass

    def browser_js(self, url_path, code, ready='', login=None, timeout=60, **kw):
        pass

    phantom_js = browser_js

def users(*logins):
    pass

@decorator
def warmup(func, *args, **kwargs):
    pass

def can_import(module):
    pass

ref_re = re.compile(r"""
(['"])(?P<view_type>\w+_view_ref)\1
\s*:\s*
(['"])
(?P<view_id>
    [.\w]+
)
""", re.VERBOSE)
class Form(object):
    def __init__(self, recordp, view=None):
        pass

    def _o2m_set_edition_view(self, descr, node, level):
        pass

    def __str__(self):
        pass

    def _process_fvg(self, model, fvg, level=2):
        pass

    def _init_from_defaults(self, model):
        pass

    def _init_from_values(self, values):
        pass

    def __getattr__(self, field):
        pass

    def _get_modifier(self, field, modifier, default=False, modmap=None, vals=None):
        pass

    _OPS = {
        '=': operator.eq,
        '==': operator.eq,
        '!=': operator.ne,
        '<': operator.lt,
        '<=': operator.le,
        '>=': operator.ge,
        '>': operator.gt,
        'in': lambda a, b: (a in b) if isinstance(b, (tuple, list)) else (b in a),
        'not in': lambda a, b: (a not in b) if isinstance(b, (tuple, list)) else (b not in a),
    }

    def _get_context(self, field):
        pass

    def __setattr__(self, field, value):
        pass

    def __enter__(self):
        pass

    def __exit__(self, etype, _evalue, _etb):
        pass

    def save(self):
        pass

    def _values_to_save(self, all_fields=False):
        pass

    def _values_to_save_(
            self, record_values, fields, view,
            changed, all_fields=False, modifiers_values=None,
            parent_link=None
    ):
        pass

    def _perform_onchange(self, fields):
        pass

    def _onchange_values(self):
        pass

    def _onchange_values_(self, fields, record):
        pass

    def _cleanup_onchange(self, descr, value, current):
        pass

class O2MForm(Form):
    def __init__(self, proxy, index=None):
        pass

    def _get_modifier(self, field, modifier, default=False, modmap=None, vals=None):
        pass

    def _onchange_values(self):
        pass

    def save(self):
        pass

    def _values_to_save(self, all_fields=False):
        pass

class UpdateDict(dict):
    def __init__(self, *args, **kwargs):
        pass

    def changed_items(self):
        pass

    def update(self, *args, **kw):
        pass

class X2MProxy(object):
    _parent = None
    _field = None
    def _assert_editable(self):
        pass

class O2MProxy(X2MProxy):
    def __init__(self, parent, field):
        pass

    def __len__(self):
        pass

    @property
    def _model(self):
        pass

    @property
    def _descr(self):
        pass

    def _command_index(self, for_record):
        pass

    def new(self):
        pass

    def edit(self, index):
        pass

    def remove(self, index):
        pass

class M2MProxy(X2MProxy, collections.Sequence):
    def __init__(self, parent, field):
        pass

    def __getitem__(self, it):
        pass

    def __len__(self):
        pass

    def __iter__(self):
        pass

    def __contains__(self, record):
        pass

    def add(self, record):
        pass

    def _get_ids(self):
        pass

    def remove(self, id=None, index=None):
        pass

    def clear(self):
        pass

def record_to_values(fields, record):
    pass

def _cleanup_from_default(type_, value):
    pass

def _get_node(view, f, *arg):
    pass

def tagged(*tags):
    pass

class TagsSelector(object):
    filter_spec_re = re.compile(r'^([+-]?)(\*|\w*)(?:/(\w*))?(?::(\w*))?(?:\.(\w*))?$')

    def __init__(self, spec):
        pass

    def check(self, test):
        pass